﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.Linq;
using IssueTracker.Business.Entity;
using IssueTracker.LinqExtension;
using System.Globalization;

namespace IssueTracker.Data
{
    public class IssueDataAccess : DataAccessComponent
    {

        private IssueTrackerDBDataContext dc;

        public IssueDataAccess()
        {
            
        }

        public Issue Create(Issue issue)
        {
            using (dc = new IssueTrackerDBDataContext())
            {

                Issue temp = base.Clone<Issue>(issue);

                dc.ObjectTrackingEnabled = true;

                dc.Issues.InsertOnSubmit(temp);

                try
                {
                    dc.SubmitChanges();

                    issue = base.Clone<Issue>(temp);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
             
            return issue;
            
        }

        public Issue Retrieve(System.Guid id)
        {
            using (dc = new IssueTrackerDBDataContext())
            {
                //Project obj = dc.Issues.Single<Issue>(proj => proj.Id == id);

                var list = from proj in dc.Issues
                           where proj.Id.Equals(id)
                           select proj;

                if (list.Count<Issue>() > 0)
                {
                    Issue obj = list.First<Issue>();
                    return obj;
                }
                else
                    return null;
            }
        }

        public Issue Update(Issue issue)
        {
            using (dc = new IssueTrackerDBDataContext())
            {
                Issue temp = base.Clone<Issue>(issue);

                dc.ObjectTrackingEnabled = true;
                dc.Issues.Attach(temp, true);

                try
                {
                    dc.SubmitChanges();

                    issue = base.Clone<Issue>(temp);
                }
                catch (ChangeConflictException ccex)
                {
                    throw new ApplicationException("The project member record that you are trying to update maybe out-dated. Please refresh and try again.", ccex);
                }
                catch (Exception ex)
                {
                    throw ex;
                }

                return issue;
            }
        }

        public void Delete(Issue issue)
        {
            using (dc = new IssueTrackerDBDataContext())
            {
                Issue temp = base.Clone<Issue>(issue);

                dc.Issues.Attach(temp);

                dc.Issues.DeleteOnSubmit(temp);

                try
                {
                    dc.SubmitChanges();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        public IEnumerable<Issue> List()
        {
            using (dc = new IssueTrackerDBDataContext())
            {
                IEnumerable<Issue> returnList = null;


                returnList = dc.Issues;

                if (returnList != null)
                    return returnList.ToList();
                else
                    return null;
            }
        }

        
        public IEnumerable<Issue> Search(Issue issue)
        {
            var predicate = PredicateBuilder.False<Issue>();

            if (issue.Title != null) 
                predicate = predicate.Or(p => p.Title.Contains(issue.Title));

            if (issue.Description != null)
                predicate = predicate.Or(p => p.Description.Contains(issue.Description));

            if (issue.LongDescription != null)
                predicate = predicate.Or(p => p.LongDescription.Contains(issue.LongDescription));

            IEnumerable<Issue> returnList = null;

            returnList = dc.Issues
                .Where(predicate);

            return returnList.ToList();
        }


        public Issue ListIssueByWorfklowInstanceId(System.Guid workflowInstanceId)
        {
            using (dc = new IssueTrackerDBDataContext())
            {
                

                var list = from issue in dc.Issues
                           where issue.WfWorkflowId == workflowInstanceId
                           select issue;

                if (list.Count<Issue>() > 0)
                {
                    Issue obj = list.First<Issue>();
                    return obj;
                }
                else
                    return null;

            }
        }

        public IEnumerable<Issue> TaskList(string userName)
        {
            using (dc = new IssueTrackerDBDataContext())
            {
                var list = from issue in dc.Issues
                           join task in dc.IssueTasks
                           on issue.Id equals task.IssueId
                           where issue.CurrentStateName != null 
                           && task.StateName != null
                           orderby issue.CreationDate descending
                           select issue;
               
                if (list != null)
                    return list.ToList();
                else
                    return null;
            }
        }
    }
}
